<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Sentences</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Sentences' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../services.html">Services</a></li><li><a href="index.html">syntax</a></li><li><a href="index.html#3">Chapter 3: Breaking into Sentences</a></li><li><b>Sentences</b></li></ul></div>
<p class="purpose">To break up the stream of words produced by the lexer into English sentences, and join each to the parse tree.</p>

<ul class="toc"><li><a href="3-snt.html#SP1">&#167;1. Sentence breaking</a></li><li><a href="3-snt.html#SP2">&#167;2. Finite state machine</a></li><li><a href="3-snt.html#SP7">&#167;7. Making sentence nodes</a></li><li><a href="3-snt.html#SP8">&#167;8. Unskipped material which is not a heading</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Sentence breaking.</b>What breaks a sentence? In ordinary English, question marks, exclamation
marks, in some cases ellipses, but mainly full stops. In Inform source text,
only full stops are used outside quoted text; but we do have to recognise the
other cases when they occur at the end of quoted matter. Moreover, we
actually subdivide a little further, because we also want to break up
rule "sentences" into their subordinate clauses. Thus, going on
punctuation, we recognise rules as having the following model:
</p>

<blockquote>
    <p>Preamble: phrase 1; phrase 2; ...; phrase N.</p>
</blockquote>

<p class="commentary">It is even, in certain limited circumstances, possible that a comma can
divide a sentence:
</p>

<blockquote>
    <p>Instead of eating, say "You really aren't hungry just now."</p>
</blockquote>

<p class="commentary">This means that context is important even here, where it might have been
expected that all we needed to do was to spot the punctuation marks.
</p>

<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Finite state machine.</b>So we carry out the sentence breaking with a simple finite state machine &mdash;
the last sentence having been a rule preamble tells us that the current one
is probably a phrase, and so on &mdash; and the following is its state. It is
inelegant that we have a singleton copy of this object and use a pointer
to it as a global variable; but it saves an awful lot of parameter-passing
in Preform grammar functions.
</p>

<pre class="definitions code-font"><span class="definition-keyword">default</span> <span class="constant-syntax">PROBLEM_REF_SYNTAX_TYPE</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span>
<span class="definition-keyword">default</span> <span class="constant-syntax">PROJECT_REF_SYNTAX_TYPE</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">NO_EXTENSION_POS</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">BEFORE_BEGINS_EXTENSION_POS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">MIDDLE_EXTENSION_POS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">AFTER_ENDS_EXTENSION_POS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">PAST_CARING_EXTENSION_POS</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">syntax_fsm_state</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">source_file</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sf</span><span class="plain-syntax">; </span><span class="comment-syntax"> reading from this source file</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ext_pos</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">*_EXTENSION_POS</span></span><span class="comment-syntax"> values: where we are in an extension</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">skipping_material_at_level</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">main_source_start_wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">inside_rule_mode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">inside_table_mode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">inside_dialogue_mode</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">inside_dialogue_mode_during</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="constant-syntax">PROBLEM_REF_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ref</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="constant-syntax">PROJECT_REF_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">project_ref</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">syntax_fsm_state</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">syntax_fsm_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">the_one_and_only</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">syntax_fsm_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax"> = &amp;</span><span class="identifier-syntax">the_one_and_only</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure syntax_fsm_state is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>Note that a reset zeroes everything out except the <span class="extract"><span class="extract-syntax">main_source_start_wn</span></span>;
that's because we reset each time we begin a round of sentence-breaking, and
there may be many such rounds on the same Inform project, but there's only
one source text start position.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Sentences::set_start_of_source</span><span class="plain-syntax">(</span><span class="reserved-syntax">syntax_fsm_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">main_source_start_wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Sentences::reset</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Sentences::reset</span></span>:<br/><a href="3-snt.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">syntax_fsm_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">is_extension</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="constant-syntax">PROBLEM_REF_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">PROJECT_REF_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">project_ref</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_rule_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_table_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_dialogue_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_dialogue_mode_during</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">skipping_material_at_level</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ref</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">project_ref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">project_ref</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">is_extension</span><span class="plain-syntax">) </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ext_pos</span><span class="plain-syntax"> = </span><span class="constant-syntax">BEFORE_BEGINS_EXTENSION_POS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ext_pos</span><span class="plain-syntax"> = </span><span class="constant-syntax">NO_EXTENSION_POS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>These are the syntax errors we will generate.
</p>

<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">UnexpectedSemicolon_SYNERROR</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ParaEndsInColon_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SentenceEndsInColon_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SentenceEndsInSemicolon_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SemicolonAfterColon_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SemicolonAfterStop_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ExtSpuriouslyContinues_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ExtNoBeginsHere_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ExtNoEndsHere_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">HeadingOverLine_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">HeadingStopsBeforeEndOfLine_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">UnexpectedDialogue_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">UnquotedDialogue_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">EmptyDialogueClause_SYNERROR</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">MisbracketedDialogueClause_SYNERROR</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>Now for the function itself. We break into bite-sized chunks, each of which is
despatched to the <span class="extract"><span class="extract-syntax">Sentences::make_node</span></span> function with a note of the punctuation
which was used to end it.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Sentences::break</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="3-snt.html#SP5" class="function-link"><span class="function-syntax">Sentences::break_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Sentences::break_into_project_copy</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="constant-syntax">PROBLEM_REF_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">project_ref</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="3-snt.html#SP5" class="function-link"><span class="function-syntax">Sentences::break_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">project_ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Sentences::break_into_extension_copy</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="constant-syntax">PROBLEM_REF_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">PROJECT_REF_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">project_ref</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="3-snt.html#SP5" class="function-link"><span class="function-syntax">Sentences::break_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">project_ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Sentences::break_inner</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">is_extension</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="constant-syntax">PROBLEM_REF_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">PROJECT_REF_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">project_ref</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))) &amp;&amp; (</span><span class="identifier-syntax">compare_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::trim_first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP5" class="function-link"><span class="function-syntax">SyntaxTree::enable_last_sentence_cache</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="3-snt.html#SP3" class="function-link"><span class="function-syntax">Sentences::reset</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">, </span><span class="identifier-syntax">is_extension</span><span class="plain-syntax">, </span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">project_ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Go into table sentence mode if necessary</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">position</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">position</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_stop_words</span><span class="plain-syntax">, </span><span class="identifier-syntax">back_up_one_word</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax">;</span>

<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">Look for a sentence break, finding the number of stop words and the stop character</span><span class="named-paragraph-number">5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_stop_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><a href="3-snt.html#SP7" class="function-link"><span class="function-syntax">Sentences::make_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax">, </span><span class="identifier-syntax">position</span><span class="plain-syntax">-1), </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">position</span><span class="plain-syntax"> + </span><span class="identifier-syntax">no_stop_words</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">back_up_one_word</span><span class="plain-syntax">) </span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">position</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">position</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>

<span class="plain-syntax">                </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Go into table sentence mode if necessary</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">        ((</span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (!(</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP7" class="function-link"><span class="function-syntax">Sentences::make_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax">), </span><span class="character-syntax">'.'</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><a href="2-st.html#SP5" class="function-link"><span class="function-syntax">SyntaxTree::disable_last_sentence_cache</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">is_extension</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_3" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message if we are missing the begin and end here sentences</span><span class="named-paragraph-number">5.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><a href="3-snt.html#SP3" class="function-link"><span class="function-syntax">Sentences::reset</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b>A table is any sentence beginning with the word "Table". (Bad news for
anyone writing "Table Mountain is a room.", of course, but there are other
ways to do that, and it seems wise to keep the syntax for tables clear,
since their entries are governed by different lexical and semantic rules.)
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Go into table sentence mode if necessary</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="function-syntax">&lt;structural-sentence&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax">))) &amp;&amp;</span>
<span class="plain-syntax">        (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::has_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt</span><span class="plain-syntax">, </span><span class="constant-syntax">TABBED_NFLAG</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_table_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_table_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5">&#167;5</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>We now come to the definition of a sentence break, which is more complicated
than might have been expected. Some people like to write paragraphs like this:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Before</span><span class="plain-syntax"> </span><span class="identifier-syntax">going</span><span class="plain-syntax"> </span><span class="identifier-syntax">north</span><span class="plain-syntax">:</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">say</span><span class="plain-syntax"> </span><span class="string-syntax">"Northward ho!"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">now</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">compass</span><span class="plain-syntax"> </span><span class="identifier-syntax">points</span><span class="plain-syntax"> </span><span class="identifier-syntax">north</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary">And properly speaking that ends with a semicolon then a paragraph break,
which is a doubled sentence division. But we forgive it as harmless, and
that forgiveness is provided by the loop arrangement below.
</p>

<p class="commentary">We also avoid the need for empty sentences, because it is not possible
for the code below to detect them: thus
</p>

<blockquote>
    <p>say "Look behind you!";;;;; now the Wug is in the Cave</p>
</blockquote>

<p class="commentary">is broken as two sentences, not six sentences of which four are empty.
Perhaps we ought to be stricter, and reject more of these dubious forms,
but at this point we have too little understanding of the semantics of
the text to risk annoying the user with problem messages.
</p>

<p class="commentary firstcommentary"><a id="SP5_2" class="paragraph-anchor"></a><b>&#167;5.2. </b>Full stops, semicolons and paragraph breaks (all rendered by the lexer as
individual words: the stroke word in the case of the latter) are always
sentence divisions. The other cases are more complicated: see below.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look for a sentence break, finding the number of stop words and the stop character</span><span class="named-paragraph-number">5.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">position</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">no_stop_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> = </span><span class="character-syntax">'?'</span><span class="plain-syntax">; </span><span class="identifier-syntax">back_up_one_word</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">at</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">stopped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">) == </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">':'</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_2_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for colon at end of paragraph</span><span class="named-paragraph-number">5.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> = </span><span class="character-syntax">'|'</span><span class="plain-syntax">; </span><span class="identifier-syntax">stopped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_dialogue_mode</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FULLSTOP_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">':'</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_2_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem for colon at end of sentence</span><span class="named-paragraph-number">5.2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">';'</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_2_3" class="named-paragraph-link"><span class="named-paragraph">Issue problem for semicolon at end of sentence</span><span class="named-paragraph-number">5.2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> = </span><span class="character-syntax">'.'</span><span class="plain-syntax">; </span><span class="identifier-syntax">stopped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">) == </span><span class="identifier-syntax">SEMICOLON_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">':'</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_2_4" class="named-paragraph-link"><span class="named-paragraph">Issue problem for semicolon after colon</span><span class="named-paragraph-number">5.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_2_5" class="named-paragraph-link"><span class="named-paragraph">Issue problem for semicolon after full stop</span><span class="named-paragraph-number">5.2.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> = </span><span class="character-syntax">';'</span><span class="plain-syntax">; </span><span class="identifier-syntax">stopped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>

<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_2_6" class="named-paragraph-link"><span class="named-paragraph">Consider if a colon divides a sentence</span><span class="named-paragraph-number">5.2.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP5_2_7" class="named-paragraph-link"><span class="named-paragraph">Consider if punctuation within a preceding quoted text divides a sentence, making an X break</span><span class="named-paragraph-number">5.2.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stopped</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">no_stop_words</span><span class="plain-syntax">++; </span><span class="identifier-syntax">at</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">'X'</span><span class="plain-syntax">) { </span><span class="comment-syntax"> X breaks are like full stops, but there is no stop word to skip over</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> = </span><span class="character-syntax">'.'</span><span class="plain-syntax">; </span><span class="identifier-syntax">back_up_one_word</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_stop_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LEXICAL_OUTPUT</span><span class="plain-syntax">, </span><span class="string-syntax">"Stop character '%c', no_stop_words %d, sentence_break %d, position %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_stop_words</span><span class="plain-syntax">, </span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax">, </span><span class="identifier-syntax">position</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_1" class="paragraph-anchor"></a><b>&#167;5.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for colon at end of paragraph</span><span class="named-paragraph-number">5.2.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ParaEndsInColon_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">-1), </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5_2">&#167;5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_2" class="paragraph-anchor"></a><b>&#167;5.2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for colon at end of sentence</span><span class="named-paragraph-number">5.2.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SentenceEndsInColon_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">), </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5_2">&#167;5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_3" class="paragraph-anchor"></a><b>&#167;5.2.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for semicolon at end of sentence</span><span class="named-paragraph-number">5.2.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SentenceEndsInSemicolon_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">), </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5_2">&#167;5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_4" class="paragraph-anchor"></a><b>&#167;5.2.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for semicolon after colon</span><span class="named-paragraph-number">5.2.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SemicolonAfterColon_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">), </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5_2">&#167;5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_5" class="paragraph-anchor"></a><b>&#167;5.2.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for semicolon after full stop</span><span class="named-paragraph-number">5.2.5</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SemicolonAfterStop_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">sentence_start</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">), </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5_2">&#167;5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_6" class="paragraph-anchor"></a><b>&#167;5.2.6. </b>Colons are normally dividers, too, but an exception is made if they come
between two apparently numerical constructions, because this suggests that
the colon is being used not as punctuation but within a literal pattern.
(For instance, "He went out at 1:34 PM." is a sentence with just one
clause, not two clauses divided by the colon; but "He went out at 1 PM:
the snow was still falling." is indeed divided. Our rule here correctly
distinguishes these cases, and although it can be fooled by really contrived
sentences &mdash; "He went out at 1: 22 Company, the Parachute Regiment, was
marching." &mdash; it's robust enough in practice. The exception is forbidden
if a line break occurs between the colon and the succeeding numeral, as
then we might be looking at switch cases in an "if".)
</p>

<p class="commentary">Note that here we are at a word position which is strictly within the word
range being sentence-broken, so that it is safe to examine both the word
before and the word after the current position.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Consider if a colon divides a sentence</span><span class="named-paragraph-number">5.2.6</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIVIDE_AT_COLON_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DIVIDE_AT_COLON_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> = </span><span class="character-syntax">':'</span><span class="plain-syntax">; </span><span class="identifier-syntax">stopped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIVIDE_AT_COLON_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">) == </span><span class="identifier-syntax">COLON_V</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Lexer::file_of_origin</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">-1) == </span><span class="identifier-syntax">Lexer::file_of_origin</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">no_stop_words</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        ((</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(*(</span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">-1))) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(*(</span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">+1))) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">+1) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> = </span><span class="character-syntax">':'</span><span class="plain-syntax">; </span><span class="identifier-syntax">stopped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5_2">&#167;5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_7" class="paragraph-anchor"></a><b>&#167;5.2.7. </b>Inform authors habitually use the punctuation in quoted text to end
sentences, just as other writers of English do. The text
</p>

<blockquote>
    <p>"Look out!" The explosion shattered the calm of the hillside.</p>
</blockquote>

<p class="commentary">is certainly intended as two sentences, not one.
</p>

<p class="commentary">An exception is made for table declarations, because a table needs to be formed as
one long sentence, and it clearly does not abide by the ordinary punctuation
rules of English. The point is that in the random line of table entries...
</p>

<blockquote>
    <p>"Of cabbages and kings."\qquad Walrus\qquad "Carroll"</p>
</blockquote>

<p class="commentary">...the full stop after "kings" has no significance: the semantics of the
table would be no different if it were not there.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Consider if punctuation within a preceding quoted text divides a sentence, making an X break</span><span class="named-paragraph-number">5.2.7</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">stopped</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; </span><span class="comment-syntax"> only look if we are not already at a division</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">no_stop_words</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; </span><span class="comment-syntax"> be sure not to elide two such texts in a row</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_table_mode</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; </span><span class="comment-syntax"> check that we are not scanning the body of a table</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Characters::isupper</span><span class="plain-syntax">(*(</span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">)))) &amp;&amp; </span><span class="comment-syntax"> and the current word begins with a capital letter</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Word::text_ending_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">-1))) { </span><span class="comment-syntax"> and the preceding one was quoted text ending in punctuation</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> = </span><span class="character-syntax">'X'</span><span class="plain-syntax">; </span><span class="identifier-syntax">stopped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5_2">&#167;5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Making sentence nodes.</b>At this point we have established that <span class="extract"><span class="extract-syntax">Sentences::make_node</span></span> is called
sequentially for every divided-off sentence in the original source text.
But we need a little machinery to skip past sentences which are being
excluded for one reason or another.
</p>

<p class="commentary">The design of Inform deliberately excludes conditional compilation in the
traditional C sense of <span class="extract"><span class="extract-syntax">#ifdef</span></span> and <span class="extract"><span class="extract-syntax">#endif</span></span>. This takes us too far from
what natural language would do, faced with the same basic issue. A book, or
a government form, would more naturally have a heading making clear that
the section beneath it is not universal in application. This is what Inform
does, too: it parses a heading to decide whether to skip the material,
and if so, the state <span class="extract"><span class="extract-syntax">sfsm-&gt;skipping_material_at_level</span></span> is set to the
level of the heading in question. We then skip all subsequent sentences
until reaching the next heading of the same or higher status, or until
reaching the "... ends here." sentence (if we are reading an extension),
or until reaching the end of the text: whichever comes first.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Sentences::make_node</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Sentences::make_node</span></span>:<br/><a href="3-snt.html#SP5">&#167;5</a>, <a href="3-snt.html#SP7_7_1_1">&#167;7.7.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heading_level</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">entering_dialogue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">entering_dialogue_for</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">begins_or_ends</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> 1 for "begins here", -1 for "ends here"</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"empty sentence generated"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">Vocabulary::identify_word_range</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">); </span><span class="comment-syntax"> a precaution to catch any late unidentified text</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Detect a change of source file, and declare it as an implicit heading</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_3" class="named-paragraph-link"><span class="named-paragraph">Detect a dividing sentence</span><span class="named-paragraph-number">7.3</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">begins_or_ends</span><span class="plain-syntax"> == -1) ||</span>
<span class="plain-syntax">        ((</span><span class="identifier-syntax">heading_level</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">heading_level</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">skipping_material_at_level</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">skipping_material_at_level</span><span class="plain-syntax"> = -1;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">skipping_material_at_level</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heading_level</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_dialogue_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">entering_dialogue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_dialogue_mode_during</span><span class="plain-syntax"> = </span><span class="identifier-syntax">entering_dialogue_for</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_4" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message if the heading incorporates a line break</span><span class="named-paragraph-number">7.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_5" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message if the heading does not end with a line break</span><span class="named-paragraph-number">7.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_6" class="named-paragraph-link"><span class="named-paragraph">Make a new HEADING node, possibly beginning to skip material</span><span class="named-paragraph-number">7.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_2" class="named-paragraph-link"><span class="named-paragraph">Reject if we have run on past the end of an extension</span><span class="named-paragraph-number">7.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7" class="named-paragraph-link"><span class="named-paragraph">Accept the new sentence as one or more nodes in the parse tree</span><span class="named-paragraph-number">7.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7_1" class="paragraph-anchor"></a><b>&#167;7.1. </b>For reasons gone into in the section on Headings below, a change of
source file (e.g., when one extension has been read in and another begins)
is declared as if it were a super-heading in the text.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Detect a change of source file, and declare it as an implicit heading</span><span class="named-paragraph-number">7.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::file_of_origin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) != </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sf</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">implicit_heading</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">implicit_heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-na.html#SP8" class="function-link"><span class="function-syntax">Annotations::write_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">implicit_heading</span><span class="plain-syntax">, </span><span class="constant-syntax">heading_level_ANNOT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-st.html#SP4" class="function-link"><span class="function-syntax">SyntaxTree::graft_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">implicit_heading</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEW_HEADING_SYNTAX_CALLBACK</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">NEW_HEADING_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">implicit_heading</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">project_ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">skipping_material_at_level</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::file_of_origin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_2" class="paragraph-anchor"></a><b>&#167;7.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Reject if we have run on past the end of an extension</span><span class="named-paragraph-number">7.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ext_pos</span><span class="plain-syntax"> == </span><span class="constant-syntax">AFTER_ENDS_EXTENSION_POS</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">begins_or_ends</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ExtSpuriouslyContinues_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ext_pos</span><span class="plain-syntax"> = </span><span class="constant-syntax">PAST_CARING_EXTENSION_POS</span><span class="plain-syntax">; </span><span class="comment-syntax"> to avoid multiply issuing this</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_3" class="paragraph-anchor"></a><b>&#167;7.3. </b>The client must define a Preform nonterminal called <span class="extract"><span class="extract-syntax">&lt;dividing-sentence&gt;</span></span>
which returns either a heading level number (1 to 10, with 1 the most
important), or <span class="extract"><span class="extract-syntax">-1</span></span> to mean that the sentence begins an extension, or
<span class="extract"><span class="extract-syntax">-2</span></span> that it ends one.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Detect a dividing sentence</span><span class="named-paragraph-number">7.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;dividing-sentence&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> -1: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ext_pos</span><span class="plain-syntax"> != </span><span class="constant-syntax">NO_EXTENSION_POS</span><span class="plain-syntax">) </span><span class="identifier-syntax">begins_or_ends</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> -2: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ext_pos</span><span class="plain-syntax"> != </span><span class="constant-syntax">NO_EXTENSION_POS</span><span class="plain-syntax">) </span><span class="identifier-syntax">begins_or_ends</span><span class="plain-syntax"> = -1; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">:</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">heading_level</span><span class="plain-syntax"> = </span><span class="constant-syntax">5</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">entering_dialogue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">entering_dialogue_for</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">:</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">heading_level</span><span class="plain-syntax"> = </span><span class="constant-syntax">5</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">entering_dialogue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">SUPERVISOR_MODULE</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">entering_dialogue_for</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;heading&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">default:</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">heading_level</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">entering_dialogue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_4" class="paragraph-anchor"></a><b>&#167;7.4. </b>We have already looked to see if the sentence could be a heading, and set
the variable <span class="extract"><span class="extract-syntax">heading_level</span></span> to be its ranking in the hierarchy (with 1,
for "volume", the highest). But we also want to check that the heading
does not have a line break in, because this is almost certainly a mistake
by the designer, and likely to be a difficult one to understand: so we
should help out if we can. Such a problem is best recovered from by
continuing regardless.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message if the heading incorporates a line break</span><span class="named-paragraph-number">7.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Lexer::break_before</span><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">) == </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">HeadingOverLine_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_5" class="paragraph-anchor"></a><b>&#167;7.5. </b>And similarly... Here we take the liberty of looking a little ahead of
the current word range in order to make the problem message more helpful:
we check that we are still looking at valid words in the lexer, just to be
on the safe side, but in fact we cannot run on past the end of the lexer
feed which fed the malformed heading, because of all of the run-off
newlines automatically added at the end of the feed of any source file.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message if the heading does not end with a line break</span><span class="named-paragraph-number">7.5</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::break_before</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)+1) != </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)+1;</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">k</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)+8) &amp;&amp;</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">k</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">lexer_wordcount</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Lexer::break_before</span><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">) != </span><span class="character-syntax">'\n'</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) ;</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">HeadingStopsBeforeEndOfLine_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_6" class="paragraph-anchor"></a><b>&#167;7.6. </b>We now have a genuine heading, and can declare it, calling a routine
in Headings to determine whether we should include the material.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make a new HEADING node, possibly beginning to skip material</span><span class="named-paragraph-number">7.6</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">new</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-na.html#SP8" class="function-link"><span class="function-syntax">Annotations::write_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">heading_level_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">heading_level</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP4" class="function-link"><span class="function-syntax">SyntaxTree::graft_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEW_HEADING_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NEW_HEADING_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">project_ref</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">skipping_material_at_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">heading_level</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_3" class="paragraph-anchor"></a><b>&#167;5.3. </b>When we finish scanning all the sentences in a given batch, and if they came
from an extension, we need to make sure we saw both beginning and end:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message if we are missing the begin and end here sentences</span><span class="named-paragraph-number">5.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ext_pos</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">BEFORE_BEGINS_EXTENSION_POS:</span>
<span class="plain-syntax">            </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ExtNoBeginsHere_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MIDDLE_EXTENSION_POS:</span>
<span class="plain-syntax">            </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ExtNoEndsHere_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Unskipped material which is not a heading.</b>Each of the sentences which are to be included is given its own node on the
parse tree, which for the time being is a direct child of the root.
Sentences are classified by their node types, the main identification
attached to each unit in the tree.
</p>

<ul class="items"><li>(a) "Nonstructural sentences", which will be subject to further parsing
work, have node type <span class="extract"><span class="extract-syntax">SENTENCE_NT</span></span> (and so will "regular sentences").
Anything we cannot place into categories (b) or (c) below will go here.
</li><li>(b) "Sentences making up rules". These are sequences of sentences in which
a preamble (ending with a colon, or in certain cases a comma) of node type
<span class="extract"><span class="extract-syntax">IMPERATIVE_NT</span></span> is followed by a sequence of phrases (ending with semicolons until
the last, which ends with a full stop or paragraph break), each of node type
<span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span>. For instance, the following produces three nodes:
</li></ul>
<blockquote>
    <p>To look upwards: say "Look out!"; something else.</p>
</blockquote>

<ul class="items"><li>(c) "Structural sentences". These demarcate the text, call for other text
or unusual matter to be included, etc.: the types in question are <span class="extract"><span class="extract-syntax">TRACE_NT</span></span>,
<span class="extract"><span class="extract-syntax">HEADING_NT</span></span>, <span class="extract"><span class="extract-syntax">INCLUDE_NT</span></span>, <span class="extract"><span class="extract-syntax">INFORM6CODE_NT</span></span>, <span class="extract"><span class="extract-syntax">BEGINHERE_NT</span></span>, <span class="extract"><span class="extract-syntax">ENDHERE_NT</span></span>,
<span class="extract"><span class="extract-syntax">TABLE_NT</span></span>, <span class="extract"><span class="extract-syntax">EQUATION_NT</span></span> and <span class="extract"><span class="extract-syntax">BIBLIOGRAPHIC_NT</span></span>.
</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>The second sentence in the source text is construed as containing
bibliographic data if it begins with a quoted piece of text, perhaps with
substitutions. For instance,
</p>

<blockquote>
    <p>"A Dream of Fair to Middling Women" by Samuel Beckett</p>
</blockquote>

<p class="commentary">This sentence is at the position matched by &lt;if-start-of-source-text&gt;.
(It may not be the first sentence read, because implied extension inclusion
sentences and options-file sentences may have been read already.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;if-start-of-source-text&gt;</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">w1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">w1</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">w1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">main_source_start_wn</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">compare_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">w1</span><span class="plain-syntax">-1, </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) { ==&gt; { </span><span class="identifier-syntax">fail</span><span class="plain-syntax"> </span><span class="identifier-syntax">nonterminal</span><span class="plain-syntax"> }; }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">w1</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    ==&gt; { </span><span class="identifier-syntax">fail</span><span class="plain-syntax"> </span><span class="identifier-syntax">nonterminal</span><span class="plain-syntax"> };</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7_7" class="paragraph-anchor"></a><b>&#167;7.7. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Accept the new sentence as one or more nodes in the parse tree</span><span class="named-paragraph-number">7.7</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_dialogue_mode</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_8" class="named-paragraph-link"><span class="named-paragraph">Make a DIALOGUE node</span><span class="named-paragraph-number">7.7.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_1" class="named-paragraph-link"><span class="named-paragraph">Convert comma-divided rule into two sentences, if this is allowed</span><span class="named-paragraph-number">7.7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_2" class="named-paragraph-link"><span class="named-paragraph">Otherwise, make a SENTENCE node</span><span class="named-paragraph-number">7.7.2</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_3" class="named-paragraph-link"><span class="named-paragraph">Convert a rule preamble to a ROUTINE node and enter rule mode</span><span class="named-paragraph-number">7.7.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_rule_mode</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_4" class="named-paragraph-link"><span class="named-paragraph">Convert to a COMMAND node and exit rule mode unless a semicolon implies more</span><span class="named-paragraph-number">7.7.4</span></a></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">';'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">UnexpectedSemicolon_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> = </span><span class="character-syntax">'.'</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> at this point we are certainly in assertion mode, not rule mode</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;structural-sentence&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax"> == -1)</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_6" class="named-paragraph-link"><span class="named-paragraph">Detect a language definition sentence and sneakily act upon it</span><span class="named-paragraph-number">7.7.6</span></a></span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax"> == -2) {</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_7" class="named-paragraph-link"><span class="named-paragraph">Detect a Preform grammar inclusion and sneakily act upon it</span><span class="named-paragraph-number">7.7.7</span></a></span>
<span class="plain-syntax">            </span><a href="2-pn.html#SP6" class="function-link"><span class="function-syntax">Node::set_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><a href="2-pn.html#SP6" class="function-link"><span class="function-syntax">Node::set_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_5" class="named-paragraph-link"><span class="named-paragraph">Convert a begins here or ends here sentence to a BEGINHERE or ENDHERE node and return</span><span class="named-paragraph-number">7.7.5</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> none of that happened, so we have a SENTENCE node for certain</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEW_NONSTRUCTURAL_SENTENCE_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">NEW_NONSTRUCTURAL_SENTENCE_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>We make an exception to the exception for the serial comma used in a list of
alternatives: thus the comma in "Aeschylus, Sophocles, or Euripides" does
not trigger this rule. We need this exception because such lists of
alternatives often occur in rule preambles, where it's the third comma
which divides rule from preamble:
</p>

<blockquote>
    <p>Instead of pushing, dropping, or taking the talisman, say "It is cursed."</p>
</blockquote>

<p class="commentary">The following is used to detect "or" in such lists.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;list-or-division&gt;</span>
<span class="plain-syntax">    ...... , </span><span class="identifier-syntax">_or</span><span class="plain-syntax"> ...... |</span>
<span class="plain-syntax">    ...... </span><span class="identifier-syntax">_or</span><span class="plain-syntax"> ......</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7_7_1" class="paragraph-anchor"></a><b>&#167;7.7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Convert comma-divided rule into two sentences, if this is allowed</span><span class="named-paragraph-number">7.7.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_rule_mode</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        &amp;&amp; ((</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">'|'</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        &amp;&amp; (</span><span class="function-syntax">&lt;comma-divisible-sentence&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_1_1" class="named-paragraph-link"><span class="named-paragraph">Look for a comma and split the sentence at it, unless in serial list</span><span class="named-paragraph-number">7.7.1.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7">&#167;7.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_1_1" class="paragraph-anchor"></a><b>&#167;7.7.1.1. </b>In such sentences a comma is read as if it were a colon. (The text up to the
comma will then be given a <span class="extract"><span class="extract-syntax">IMPERATIVE_NT</span></span> node and the text beyond the comma
will make a <span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span> node.)
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look for a comma and split the sentence at it, unless in serial list</span><span class="named-paragraph-number">7.7.1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">earliest_comma_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Set earliest comma to position after the or, if there is one</span><span class="named-paragraph-number">7.7.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">, </span><span class="identifier-syntax">BW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;list-comma-division&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">earliest_comma_position</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;list-comma-division&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">BW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;list-comma-division&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP7" class="function-link"><span class="function-syntax">Sentences::make_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::up_to</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">)), </span><span class="character-syntax">':'</span><span class="plain-syntax">); </span><span class="comment-syntax"> rule preamble stopped with a colon</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP7" class="function-link"><span class="function-syntax">Sentences::make_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">BW</span><span class="plain-syntax">, </span><span class="character-syntax">'.'</span><span class="plain-syntax">); </span><span class="comment-syntax"> rule body with one sentence, stopped with a stop</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7_1">&#167;7.7.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_1_1_1" class="paragraph-anchor"></a><b>&#167;7.7.1.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Set earliest comma to position after the or, if there is one</span><span class="named-paragraph-number">7.7.1.1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;list-or-division&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">BW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;list-or-division&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">earliest_comma_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">BW</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7_1_1">&#167;7.7.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_2" class="paragraph-anchor"></a><b>&#167;7.7.2. </b>At this point we know that the text <span class="extract"><span class="extract-syntax">W</span></span> will make one and only
one sentence node in the parse tree, so we may as well create and SyntaxTree::graft it
now. There are a number of special cases with variant node types, but the
commonest outcome is a SENTENCE node, so that's what we shall assume for now.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Otherwise, make a SENTENCE node</span><span class="named-paragraph-number">7.7.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">new</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SENTENCE_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP4" class="function-link"><span class="function-syntax">SyntaxTree::graft_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7">&#167;7.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_3" class="paragraph-anchor"></a><b>&#167;7.7.3. </b>Rules are sequences of phrases with a preamble in front, which we detect by
its terminating colon. For instance:
</p>

<blockquote>
    <p>To look upwards: say "Look out!"; something else.</p>
</blockquote>

<p class="commentary">(which arrives at this routine as three separate "sentences") will produce
nodes with type <span class="extract"><span class="extract-syntax">IMPERATIVE_NT</span></span>, <span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span> and <span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span> respectively.
</p>

<p class="commentary">This paragraph of code might look as if it should only be used in assertion
mode, not in rule mode, because how can a rule preamble legally occur in
the middle of another rule? But in fact it can, in two ways. One is the
officially sanctioned way to make a definition with a complex phrase:
</p>

<blockquote>
    <p>Definition: a supporter is wobbly: if the player is on it, decide yes; decide no.</p>
</blockquote>

<p class="commentary">This produces four nodes: <span class="extract"><span class="extract-syntax">IMPERATIVE_NT</span></span>, <span class="extract"><span class="extract-syntax">IMPERATIVE_NT</span></span>, <span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span> and
<span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span> respectively.
</p>

<p class="commentary">The other arises somewhat less officially when people treat phrases as
if they were C (or Inform 6) statements, always to be terminated with
semicolons, and also run two rules together with no skipped paragraph
between:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">To</span><span class="plain-syntax"> </span><span class="identifier-syntax">do</span><span class="plain-syntax"> </span><span class="identifier-syntax">one</span><span class="plain-syntax"> </span><span class="identifier-syntax">thing</span><span class="plain-syntax">: </span><span class="identifier-syntax">something</span><span class="plain-syntax"> </span><span class="identifier-syntax">here</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">To</span><span class="plain-syntax"> </span><span class="identifier-syntax">do</span><span class="plain-syntax"> </span><span class="identifier-syntax">another</span><span class="plain-syntax"> </span><span class="identifier-syntax">thing</span><span class="plain-syntax">: </span><span class="identifier-syntax">something</span><span class="plain-syntax"> </span><span class="identifier-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">here</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary">A strict reading of our rules would oblige us to consider "To do another
thing:" as a phrase within the definition of "To do one thing", and
we would then have to issue a problem message. But this would be pettifogging.
(People who habitually shuffle phrases about in their editors tend not to
want to fuss about changing the punctuation of the last to a full stop
instead of a semicolon. We may lament this, but it is so.)
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Convert a rule preamble to a ROUTINE node and enter rule mode</span><span class="named-paragraph-number">7.7.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">list_node_type</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> == </span><span class="character-syntax">':'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_rule_mode</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ControlStructures::detect</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">            </span><a href="2-pn.html#SP6" class="function-link"><span class="function-syntax">Node::set_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_entry_node_type</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax">            </span><a href="2-na.html#SP8" class="function-link"><span class="function-syntax">Annotations::write_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">colon_block_command_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_rule_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><a href="2-pn.html#SP6" class="function-link"><span class="function-syntax">Node::set_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_node_type</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_rule_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7">&#167;7.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_4" class="paragraph-anchor"></a><b>&#167;7.7.4. </b>Subsequent commands are divided by semicolons, and any failure of a
semicolon to appear indicates an end of the rule.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Convert to a COMMAND node and exit rule mode unless a semicolon implies more</span><span class="named-paragraph-number">7.7.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">list_node_type</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP6" class="function-link"><span class="function-syntax">Node::set_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_entry_node_type</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stop_character</span><span class="plain-syntax"> != </span><span class="character-syntax">';'</span><span class="plain-syntax">) </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_rule_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7">&#167;7.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_5" class="paragraph-anchor"></a><b>&#167;7.7.5. </b>Finally, we must tidy away the previously detected "begins here" and
"ends here" sentences into nodes on the tree.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Convert a begins here or ends here sentence to a BEGINHERE or ENDHERE node and return</span><span class="named-paragraph-number">7.7.5</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">begins_or_ends</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="2-pn.html#SP6" class="function-link"><span class="function-syntax">Node::set_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">BEGINHERE_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::trim_last_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::trim_last_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">BEGIN_OR_END_HERE_SYNTAX_CALLBACK</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">BEGIN_OR_END_HERE_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">begins_or_ends</span><span class="plain-syntax"> == -1) {</span>
<span class="plain-syntax">        </span><a href="2-pn.html#SP6" class="function-link"><span class="function-syntax">Node::set_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">ENDHERE_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::trim_last_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::trim_last_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">BEGIN_OR_END_HERE_SYNTAX_CALLBACK</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">BEGIN_OR_END_HERE_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7">&#167;7.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_6" class="paragraph-anchor"></a><b>&#167;7.7.6. </b>Why are we taking a sneak look at this sentence now? Because it affects
which headings we read the contents of. If we waited until sentence traverses,
it would be too late.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Detect a language definition sentence and sneakily act upon it</span><span class="named-paragraph-number">7.7.6</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">LANGUAGE_ELEMENT_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LANGUAGE_ELEMENT_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;language-modifying-sentence&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><a href="2-na.html#SP8" class="function-link"><span class="function-syntax">Annotations::write_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">language_element_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7">&#167;7.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_7" class="paragraph-anchor"></a><b>&#167;7.7.7. </b>And for similar reasons:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Detect a Preform grammar inclusion and sneakily act upon it</span><span class="named-paragraph-number">7.7.7</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;language-modifying-sentence&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">, </span><span class="string-syntax">"%+W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LoadPreform::parse_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">)</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7">&#167;7.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_8" class="paragraph-anchor"></a><b>&#167;7.7.8. </b>Dialogue sections have their own syntactic conventions, which are enforced
here. This hand-tooled parser is annoyingly long to write out, but only in
order to catch improbable unmatched-bracket errors with tidy error messages.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make a DIALOGUE node</span><span class="named-paragraph-number">7.7.8</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIALOGUE_WARNING_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">contains_dialogue</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DIALOGUE_WARNING_SYNTAX_CALLBACK</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">contains_dialogue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opening_word</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">opening_word</span><span class="plain-syntax"> == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_8_1" class="named-paragraph-link"><span class="named-paragraph">This is a dialogue cue</span><span class="named-paragraph-number">7.7.8.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">opening_word</span><span class="plain-syntax"> == </span><span class="identifier-syntax">DOUBLEDASH_V</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">opening_word</span><span class="plain-syntax"> == </span><span class="identifier-syntax">LEFTARROW_V</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">opening_word</span><span class="plain-syntax"> == </span><span class="identifier-syntax">RIGHTARROW_V</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_8_2" class="named-paragraph-link"><span class="named-paragraph">This is a dialogue choice</span><span class="named-paragraph-number">7.7.8.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_8_3" class="named-paragraph-link"><span class="named-paragraph">Otherwise this has to be a dialogue line</span><span class="named-paragraph-number">7.7.8.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7">&#167;7.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_8_1" class="paragraph-anchor"></a><b>&#167;7.7.8.1. </b>Here we are trying to match <span class="extract"><span class="extract-syntax">(Cue notes.)</span></span>.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">This is a dialogue cue</span><span class="named-paragraph-number">7.7.8.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">CW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)+1, </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)-1);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_CUE_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-na.html#SP8" class="function-link"><span class="function-syntax">Annotations::write_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">dialogue_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_dialogue_mode_during</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><a href="2-na.html#SP8" class="function-link"><span class="function-syntax">Annotations::write_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">dialogue_during_text_w1_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_dialogue_mode_during</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><a href="2-na.html#SP8" class="function-link"><span class="function-syntax">Annotations::write_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">dialogue_during_text_w2_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inside_dialogue_mode_during</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP4" class="function-link"><span class="function-syntax">SyntaxTree::graft_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="3-snt.html#SP11" class="function-link"><span class="function-syntax">Sentences::add_dialogue_clauses</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7_8">&#167;7.7.8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_8_2" class="paragraph-anchor"></a><b>&#167;7.7.8.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">This is a dialogue choice</span><span class="named-paragraph-number">7.7.8.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">clauses_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">clauses_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">clauses_from</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">speech_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">clauses_from</span><span class="plain-syntax">, </span><span class="identifier-syntax">speech_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">speech_from</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">clauses_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">speech_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">+1; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">CW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">clauses_from</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">clauses_to</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">TW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">speech_from</span><span class="plain-syntax">, </span><span class="identifier-syntax">speech_to</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">new</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_CHOICE_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-na.html#SP8" class="function-link"><span class="function-syntax">Annotations::write_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">dialogue_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP4" class="function-link"><span class="function-syntax">SyntaxTree::graft_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">TW</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">selection</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_SELECTION_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">selection</span><span class="plain-syntax">, </span><span class="identifier-syntax">TW</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-st.html#SP6" class="function-link"><span class="function-syntax">SyntaxTree::graft</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">selection</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP11" class="function-link"><span class="function-syntax">Sentences::add_dialogue_clauses</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7_8">&#167;7.7.8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_8_3" class="paragraph-anchor"></a><b>&#167;7.7.8.3. </b>Here we are trying to match <span class="extract"><span class="extract-syntax">Speaker (notes): "Speech."</span></span>.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Otherwise this has to be a dialogue line</span><span class="named-paragraph-number">7.7.8.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">colon_at</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_8_3_1" class="named-paragraph-link"><span class="named-paragraph">Find the colon position</span><span class="named-paragraph-number">7.7.8.3.1</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">speaker_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">colon_at</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">clauses_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">colon_at</span><span class="plain-syntax">, </span><span class="identifier-syntax">clauses_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">colon_at</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">speech_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">colon_at</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">speech_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_8_3_2" class="named-paragraph-link"><span class="named-paragraph">Trim away bracketed clauses after the speaker name</span><span class="named-paragraph-number">7.7.8.3.2</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">SW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">speaker_from</span><span class="plain-syntax">, </span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">CW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">clauses_from</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">clauses_to</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">TW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">speech_from</span><span class="plain-syntax">, </span><span class="identifier-syntax">speech_to</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;quoted-text&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">TW</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_8_3_3" class="named-paragraph-link"><span class="named-paragraph">Dialogue speech not in double-quotes</span><span class="named-paragraph-number">7.7.8.3.3</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">new</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_LINE_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-na.html#SP8" class="function-link"><span class="function-syntax">Annotations::write_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">dialogue_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP4" class="function-link"><span class="function-syntax">SyntaxTree::graft_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">speaker</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_SPEAKER_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">speaker</span><span class="plain-syntax">, </span><span class="identifier-syntax">SW</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">speech</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_SPEECH_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">speech</span><span class="plain-syntax">, </span><span class="identifier-syntax">TW</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP6" class="function-link"><span class="function-syntax">SyntaxTree::graft</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">speaker</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP6" class="function-link"><span class="function-syntax">SyntaxTree::graft</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">speech</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP11" class="function-link"><span class="function-syntax">Sentences::add_dialogue_clauses</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7_8">&#167;7.7.8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_8_3_1" class="paragraph-anchor"></a><b>&#167;7.7.8.3.1. </b>The colon should always occur outside of parentheses, but if we can't find
one in that happy condition, we just find the first one that's there (for the
sake of issuing better problem messages: it won't lead to valid syntax).
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find the colon position</span><span class="named-paragraph-number">7.7.8.3.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">COLON_V</span><span class="plain-syntax">)) </span><span class="identifier-syntax">colon_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">colon_at</span><span class="plain-syntax"> == -1)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">COLON_V</span><span class="plain-syntax">) { </span><span class="identifier-syntax">colon_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">colon_at</span><span class="plain-syntax"> == -1) </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_8_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Not a dialogue line after all</span><span class="named-paragraph-number">7.7.8.3.1.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7_8_3">&#167;7.7.8.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_8_3_2" class="paragraph-anchor"></a><b>&#167;7.7.8.3.2. </b>Similarly, we want to trim away bracketed clauses in a way which respects
bracket nesting, and if we can't do that then the text is certainly erroneous:
but we trim away the best we can for the sake of reporting a good problem.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Trim away bracketed clauses after the speaker name</span><span class="named-paragraph-number">7.7.8.3.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">cut</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&gt;=</span><span class="identifier-syntax">speaker_from</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">--) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">clauses_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">cut</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cut</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&gt;=</span><span class="identifier-syntax">speaker_from</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">--)</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">clauses_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">cut</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cut</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP7_7_8_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Not a dialogue line after all</span><span class="named-paragraph-number">7.7.8.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">speaker_from</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">speaker_from</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">clauses_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">speaker_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">-1; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7_8_3">&#167;7.7.8.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_8_3_1_1" class="paragraph-anchor"></a><b>&#167;7.7.8.3.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Not a dialogue line after all</span><span class="named-paragraph-number">7.7.8.3.1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">UnexpectedDialogue_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">UNKNOWN_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP4" class="function-link"><span class="function-syntax">SyntaxTree::graft_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7_8_3_1">&#167;7.7.8.3.1</a> and <a href="3-snt.html#SP7_7_8_3_2">&#167;7.7.8.3.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_7_8_3_3" class="paragraph-anchor"></a><b>&#167;7.7.8.3.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Dialogue speech not in double-quotes</span><span class="named-paragraph-number">7.7.8.3.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">UnquotedDialogue_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">UNKNOWN_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-st.html#SP4" class="function-link"><span class="function-syntax">SyntaxTree::graft_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP7_7_8_3">&#167;7.7.8.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>This is shared by both cues and lines, each of which can have multiple
clauses in brackets. Punctuation divides these only outside of brackets, so
<span class="extract"><span class="extract-syntax">(hello, there), (and. here.)</span></span> divides only at the central comma, and results
in two <span class="extract"><span class="extract-syntax">DIALOGUE_CLAUSE_NT</span></span> nodes: one for <span class="extract"><span class="extract-syntax">hello, there</span></span> and the other for
<span class="extract"><span class="extract-syntax">and. here</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Sentences::add_dialogue_clauses</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Sentences::add_dialogue_clauses</span></span>:<br/><a href="3-snt.html#SP7_7_8_1">&#167;7.7.8.1</a>, <a href="3-snt.html#SP7_7_8_2">&#167;7.7.8.2</a>, <a href="3-snt.html#SP7_7_8_3">&#167;7.7.8.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">CW</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">), </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            ((</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FULLSTOP_V</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">SEMICOLON_V</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> = </span><span class="identifier-syntax">start</span><span class="plain-syntax">, </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">-1;</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP11_1" class="named-paragraph-link"><span class="named-paragraph">Add a clause</span><span class="named-paragraph-number">11.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">+1;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">MisbracketedDialogueClause_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">CW</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">start</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> = </span><span class="identifier-syntax">start</span><span class="plain-syntax">, </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">CW</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-snt.html#SP11_1" class="named-paragraph-link"><span class="named-paragraph">Add a clause</span><span class="named-paragraph-number">11.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11_1" class="paragraph-anchor"></a><b>&#167;11.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add a clause</span><span class="named-paragraph-number">11.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">a</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">b</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">a</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">b</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">a</span><span class="plain-syntax">++, </span><span class="identifier-syntax">b</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">b</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FULLSTOP_V</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">b</span><span class="plain-syntax">) == </span><span class="identifier-syntax">SEMICOLON_V</span><span class="plain-syntax">)) </span><span class="identifier-syntax">b</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">b</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">a</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="3-snt.html#SP12" class="function-link"><span class="function-syntax">Sentences::syntax_problem</span></a><span class="plain-syntax">(</span><span class="constant-syntax">EmptyDialogueClause_SYNERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">CW</span><span class="plain-syntax">, </span><span class="identifier-syntax">sfsm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ref</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">a</span><span class="plain-syntax">, </span><span class="identifier-syntax">b</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">clause</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_CLAUSE_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-st.html#SP6" class="function-link"><span class="function-syntax">SyntaxTree::graft</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-snt.html#SP11">&#167;11</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>Some tools using this module will want to push simple error messages out to
the command line; others will want to translate them into elaborate problem
texts in HTML. So the client is allowed to define <span class="extract"><span class="extract-syntax">PROBLEM_SYNTAX_CALLBACK</span></span>
to some routine of her own, gazumping this one.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Sentences::syntax_problem</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Sentences::syntax_problem</span></span>:<br/><a href="3-snt.html#SP5_2_1">&#167;5.2.1</a>, <a href="3-snt.html#SP5_2_2">&#167;5.2.2</a>, <a href="3-snt.html#SP5_2_3">&#167;5.2.3</a>, <a href="3-snt.html#SP5_2_4">&#167;5.2.4</a>, <a href="3-snt.html#SP5_2_5">&#167;5.2.5</a>, <a href="3-snt.html#SP7_2">&#167;7.2</a>, <a href="3-snt.html#SP7_4">&#167;7.4</a>, <a href="3-snt.html#SP7_5">&#167;7.5</a>, <a href="3-snt.html#SP5_3">&#167;5.3</a>, <a href="3-snt.html#SP7_7">&#167;7.7</a>, <a href="3-snt.html#SP7_7_8_3_1_1">&#167;7.7.8.3.1.1</a>, <a href="3-snt.html#SP7_7_8_3_3">&#167;7.7.8.3.3</a>, <a href="3-snt.html#SP11">&#167;11</a>, <a href="3-snt.html#SP11_1">&#167;11.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">err_no</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROBLEM_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PROBLEM_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">err_no</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROBLEM_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="string-syntax">"%+W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">err_no</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UnexpectedSemicolon_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::with_text</span><span class="plain-syntax">(</span><span class="string-syntax">"unexpected semicolon in sentence: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ParaEndsInColon_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::with_text</span><span class="plain-syntax">(</span><span class="string-syntax">"paragraph ends with a colon: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SentenceEndsInColon_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::with_text</span><span class="plain-syntax">(</span><span class="string-syntax">"paragraph ends with a colon and full stop: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SentenceEndsInSemicolon_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::with_text</span><span class="plain-syntax">(</span><span class="string-syntax">"paragraph ends with a semicolon and full stop: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SemicolonAfterColon_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::with_text</span><span class="plain-syntax">(</span><span class="string-syntax">"paragraph ends with a colon and semicolon: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SemicolonAfterStop_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::with_text</span><span class="plain-syntax">(</span><span class="string-syntax">"paragraph ends with a full stop and semicolon: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ExtNoBeginsHere_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::nowhere</span><span class="plain-syntax">(</span><span class="string-syntax">"extension has no beginning"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ExtNoEndsHere_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::nowhere</span><span class="plain-syntax">(</span><span class="string-syntax">"extension has no end"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ExtSpuriouslyContinues_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::with_text</span><span class="plain-syntax">(</span><span class="string-syntax">"extension continues after end: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">HeadingOverLine_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::with_text</span><span class="plain-syntax">(</span><span class="string-syntax">"heading contains a line break: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">HeadingStopsBeforeEndOfLine_SYNERROR:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Errors::with_text</span><span class="plain-syntax">(</span><span class="string-syntax">"heading stops before end of line: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="2-spc.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresschapter"><a href="2-st.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresscurrent">snt</li><li class="progressnextoff">&#10095;</li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

